import { useEffect, useCallback } from 'react';

import { Toaster, toast } from 'sonner';
import { useClientContext, getNodeForm, FlowNodeEntity } from '@flowgram.ai/free-layout-editor';
import { useService } from '@flowgram.ai/free-layout-editor';

import { cn } from '@/lib/utils';
import { useFlowContext } from '@/context/flow-context';

import { Button } from '../ui/button';
import { CustomService } from '../../services';

export function Save(props: { disabled: boolean }) {
  const customService = useService(CustomService);
  const flowContext = useFlowContext();
  const clientContext = useClientContext();

  const updateValidateData = useCallback(() => {
    const allForms = clientContext.document.getAllNodes().map((node) => getNodeForm(node));
    const count = allForms.filter((form) => form?.state.invalid).length;
  }, [clientContext]);

  /**
   * Validate all node and Save
   */
  const onSave = useCallback(async () => {
    const allForms = clientContext.document.getAllNodes().map((node) => getNodeForm(node));
    await Promise.all(allForms.map(async (form) => form?.validate()));
    console.log('flowName1', flowContext.name);
    const flowName = flowContext.name || '';
    console.log('save data', flowName);
    if (flowName === '') {
      console.log('flowName', flowName);
      toast('请输入工作流名称');
      return;
    }

    const saveData = {
      id: flowContext.id || 0,
      name: flowName,
      data: clientContext.document.toJSON(),
      format: 'flowgram',
    };
    try {
      console.log('saveData', saveData);
      const result = await customService.saveFlow(JSON.stringify(saveData));
      flowContext.setFlow({
        ...flowContext,
        id: result.id,
      })
      console.log('>>>>> result: ', result);
    } catch (error) {
      console.log('>>>>> error: ', error);
    }
  }, [flowContext, clientContext]);

  /**
   * Listen single node validate
   */
  useEffect(() => {
    const listenSingleNodeValidate = (node: FlowNodeEntity) => {
      const form = getNodeForm(node);
      if (form) {
        const formValidateDispose = form.onValidate(() => updateValidateData());
        node.onDispose(() => formValidateDispose.dispose());
      }
    };
    clientContext.document.getAllNodes().map((node) => listenSingleNodeValidate(node));
    const dispose = clientContext.document.onNodeCreate(({ node }) =>
      listenSingleNodeValidate(node)
    );
    return () => dispose.dispose();
  }, [clientContext]);

  return (
    <>
      <Toaster />
      <Button disabled={props.disabled} onClick={onSave} className={cn('h-8 md:text-xs')}>
        保存
      </Button>
    </>
  );
}
